////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2009 Daniel F. Hanson
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////

namespace SilverLua
{
   /// <summary>
   /// A single execution command for the SilverLua VM.
   /// </summary>
   public class Instruction
   {
      public Opcode Opcode { get; private set; }
      public OperandType[] OperandTypes { get; private set; }
      public int[] OperandValues { get; private set; }
      public int OperandCount { get { return OperandValues.Length; } }

      public Instruction(Opcode opcode, OperandType[] types, int[] values)
      {
         Opcode = opcode;
         OperandTypes = types;
         OperandValues = values;
      }
   }

   public enum Opcode
   {
      /// <summary>
      /// move dest src
      /// </summary>
      Move,
      /// <summary>
      /// mosk dest src test
      /// </summary>
      MoveOrSkip,
      /// <summary>
      /// ggbl dest index
      /// </summary>
      GetGlobal,
      /// <summary>
      /// sgbl index src
      /// </summary>
      SetGlobal,
      /// <summary>
      /// gtbl dest table index
      /// </summary>
      GetTable,
      /// <summary>
      /// stbl table index src
      /// </summary>
      SetTable,
      /// <summary>
      /// ctbl table
      /// </summary>
      CreateTable,
      /// <summary>
      /// add dest op1 op2
      /// </summary>
      Add,
      /// <summary>
      /// sub dest op1 op2
      /// </summary>
      Subtract,
      /// <summary>
      /// mul dest op1 op2
      /// </summary>
      Multiply,
      /// <summary>
      /// div dest op1 op2
      /// </summary>
      Divide,
      /// <summary>
      /// exp dest op1 op2
      /// </summary>
      Exponent,
      /// <summary>
      /// neg dest src
      /// </summary>
      Negate,
      /// <summary>
      /// mod dest op1 op2
      /// </summary>
      Modulo,
      /// <summary>
      /// cat dest op1 op2
      /// </summary>
      Concatenate,
      /// <summary>
      /// eq dest op1 op2
      /// </summary>
      Equal,
      /// <summary>
      /// neq dest op1 op2
      /// </summary>
      NotEqual,
      /// <summary>
      /// ls dest op1 op2
      /// </summary>
      Less,
      /// <summary>
      /// lseq dest op1 op2
      /// </summary>
      LessEqual,
      /// <summary>
      /// not dest src
      /// </summary>
      Not,
      /// <summary>
      /// len dest table
      /// </summary>
      Length,
      /// <summary>
      /// jmp label
      /// </summary>
      Jump,
      /// <summary>
      /// cjmp label src test
      /// </summary>
      ConditionalJump,
      /// <summary>
      /// call function param count
      /// </summary>
      Call,
      /// <summary>
      /// ret begin count
      /// </summary>
      Return,
      /// <summary>
      /// func dest chunk params
      /// </summary>
      Function
   }

   public enum OperandType
   {
      Value,
      Upvalue,
      Parameter,
      Return,
      IntegerLiteral,
      FloatLiteral,
      StringLiteral,
      BooleanLiteral,
      NilLiteral
   }
}
